package edu.uwlax.cs.oayonlinestore.client.gui.shared;

import java.util.Iterator;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

import edu.uwlax.cs.oayonlinestore.client.OnlinestoreRService;
import edu.uwlax.cs.oayonlinestore.client.Order;
import edu.uwlax.cs.oayonlinestore.client.utils.Currency;
import edu.uwlax.cs.oayonlinestore.client.utils.DefaultAsyncCallback;
import edu.uwlax.cs.oayonlinestore.client.utils.DekoTable;
import edu.uwlax.cs.oayonlinestore.vo.GiftCardVO;
import edu.uwlax.cs.oayonlinestore.vo.OrderExtendedVO;
import edu.uwlax.cs.oayonlinestore.vo.OrderItemVO;

public class CartTable extends DekoTable {

	private class DeleteHandler extends DefaultAsyncCallback implements
			ClickListener {

		private int orderItemID;

		public DeleteHandler(int orderItemID) {
			super();
			this.orderItemID = orderItemID;
		}

		public void onClick(Widget arg0) {
			OnlinestoreRService.Util.getInstance().deleteOrderItem(orderItemID,
					this);
		}

		public void onSuccess(Object arg0) {
			refresh();
			Order.get().update();
		}
	}

	private class LoadHandler extends DefaultAsyncCallback {
		public void onSuccess(Object arg0) {
			setOrder((OrderExtendedVO) arg0);
		}
	}

	private class SetQuantityHandler extends DefaultAsyncCallback implements
			ClickListener {

		private TextBox edit;

		private int orderItemID;

		public SetQuantityHandler(TextBox edit, int orderItemID) {
			super();
			this.edit = edit;
			this.orderItemID = orderItemID;
		}

		public void onClick(Widget arg0) {
			try {
				int am = Integer.parseInt(edit.getText());
				OnlinestoreRService.Util.getInstance().setOrderItemAmount(
						orderItemID, am, this);
			} catch (NumberFormatException e) {
				Window.alert("'" + edit.getText() + "' is not a valid number.");
			}
		}

		public void onSuccess(Object arg0) {
			refresh();
			Order.get().update();
		}
	}

	private class RemoveGiftCardHandler extends DefaultAsyncCallback implements
			ClickListener {

		private int giftCardID;

		public RemoveGiftCardHandler(int giftCardID) {
			super();
			this.giftCardID = giftCardID;
		}

		public void onClick(Widget arg0) {
			OnlinestoreRService.Util.getInstance().removeGiftCardFromOrder(
					orderID, giftCardID, this);
		}

		public void onSuccess(Object arg0) {
			refresh();
			Order.get().update();
		}
	}

	private int orderID = 0;

	public CartTable() {
		super();
		addTitle("Brand");
		addTitle("Product");
		addTitle("Price/#");
		addTitle("#");
		addTitle("Discount");
		addTitle("Price");
		addTitle("");
	}

	private void addGiftcard(GiftCardVO gc) {
		AddRow r = addRow();
		r.add("Gift Card").setColspan(5);
		r.add(new Currency(-gc.getMoneyValue()));
		r.add(new Button("delete", new RemoveGiftCardHandler(gc.getId())));
	}

	private void addNoOrder() {
		AddRow r = addRow();
		r.add("No Items Selected").setColspan(7).setHAlign(r.CENTER);
	}

	private void addOrderItem(OrderItemVO item) {
		AddRow r = addRow();
		r.add(item.getProduct().getBrand());
		r.add(item.getProduct().getName());
		r.add(new Currency(item.getPrice()));
		r.add(createSetQuantityField(item.getQuantity(), item.getId()));
		r.add(item.getDiscount()+"%").setHAlign(r.RIGHT);
		r.add(new Currency(item.getTotal()));
		r.add(new Button("delete", new DeleteHandler(item.getId())));
	}

	private void addShipping(Currency val) {
		AddRow r = addRow();
		r.add("Shipping").setColspan(5);
		r.add(val);
		r.add("");
	}

	private void addTax(float tax, Currency val) {
		AddRow r = addRow();
		r.add("Tax (" + tax + "%)").setColspan(5);
		r.add(val);
		r.add("");
	}

	private void addTotal(Currency val) {
		AddRow r = addRow();
		r.add("Total").setColspan(5);
		r.add(val).bold();
		r.add("");
	}

	private Widget createSetQuantityField(int quantity, int id) {
		TextBox tb = new TextBox();
		tb.setText(String.valueOf(quantity));
		tb.setWidth("32px");
		tb.setTextAlignment(TextBox.ALIGN_RIGHT);
		HorizontalPanel hp = new HorizontalPanel();
		hp.add(tb);
		hp.add(new Button("set", new SetQuantityHandler(tb, id)));
		return hp;
	}

	public void loadOrder(int orderID) {
		this.orderID = orderID;
		refresh();
	}

	public void refresh() {
		if (orderID != 0) {
			OnlinestoreRService.Util.getInstance().getOrderExtended(orderID,
					new LoadHandler());
			cleanExceptHeader();
		} else {
			cleanExceptHeader();
			addNoOrder();
		}
	}

	private void setOrder(OrderExtendedVO order) {
		if (order.getOrderItems() != null)
			for (Iterator i = order.getOrderItems().iterator(); i.hasNext();)
				addOrderItem((OrderItemVO) i.next());

		if (order.getGiftCards() != null)
			for (Iterator i = order.getGiftCards().iterator(); i.hasNext();)
				addGiftcard((GiftCardVO) i.next());

		if ((order.getOrderItems() == null) && order.getGiftCards() == null)
			addNoOrder();
		else {
			addShipping(new Currency(order.getShipping()));
			addTax(order.getTaxPercent(), new Currency(order.getTaxMoney()));
			addTotal(new Currency(order.getTotal()));
		}
	}

}
